﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using JetBrains.Annotations;
#if TASKSUPPORT
using System.Threading.Tasks;
#endif
#if !NETFX_CORE
using System.Windows.Navigation;
#else
using Windows.UI.Xaml.Navigation;
#endif
using MugenMvvmToolkit.Interfaces.ViewModels;
using MugenMvvmToolkit.Interfaces.Views;
using MugenMvvmToolkit.Models;

namespace MugenMvvmToolkit.Interfaces
{
    /// <summary>
    ///     Represent the interface for navigation provider.
    /// </summary>
    public interface INavigationProvider : IDisposable
    {
        /// <summary>
        /// Gets the <see cref="INavigationService"/>.
        /// </summary>
        [NotNull]
        INavigationService NavigationService { get; }

        /// <summary>
        /// Gets the cache policy, if any.
        /// </summary>
        [CanBeNull]
        INavigationCachePolicy CachePolicy { get; }

        /// <summary>
        /// Gets the operation result policy, if any.
        /// </summary>
        [CanBeNull]
        INavigationOperationResultPolicy OperationResultPolicy { get; }

        /// <summary>
        /// Gets the active view model.
        /// </summary>
        [CanBeNull]
        IViewModel CurrentViewModel { get; }

#if SILVERLIGHT
        /// <summary>
        ///     Navigates to the specified uri.
        /// </summary>
        /// <param name="uri">
        ///     The specified <see cref="Uri" />.
        /// </param>
        /// <param name="uriParameters">The specified uri-parameters, if any.</param>
        INavigationResult Navigate([NotNull]Uri uri,[CanBeNull] IDictionary<string, string> uriParameters);

        /// <summary>
        ///     Navigates to the specified view model.
        /// </summary>
        /// <param name="viewModel">
        ///     The specified <see cref="IViewModel" />.
        /// </param>
        /// <param name="uriParameters">The specified uri-parameters, if any.</param>
        /// <param name="viewName">The specified view binding name, if any.</param>
        INavigationResult Navigate([NotNull]IViewModel viewModel, [CanBeNull] IDictionary<string, string> uriParameters, string viewName = null);
#endif

#if WPF
        /// <summary>
        ///     Navigates to the specified uri.
        /// </summary>
        /// <param name="uri">
        ///     The specified <see cref="Uri" />.
        /// </param>
        /// <param name="parameter">A <see cref="T:System.Object"/> that contains data to be used for processing during navigation.</param>
        /// <param name="uriParameters">The specified uri-parameters, if any.</param>
        INavigationResult Navigate([NotNull]Uri uri, [CanBeNull]object parameter, [CanBeNull]IDictionary<string, string> uriParameters);

        /// <summary>
        ///     Navigates to the specified view model.
        /// </summary>
        /// <param name="viewModel">
        ///     The specified <see cref="IViewModel" />.
        /// </param>
        /// <param name="parameter">A <see cref="T:System.Object"/> that contains data to be used for processing during navigation.</param>
        /// <param name="uriParameters">The specified uri-parameters, if any.</param>
        /// <param name="viewName">The specified view binding name, if any.</param>
        INavigationResult Navigate([NotNull]IViewModel viewModel, [CanBeNull]IDictionary<string, string> uriParameters, [CanBeNull]object parameter, string viewName = null);
#endif

#if NETFX_CORE
        /// <summary>
        ///     Navigates to the specified view model.
        /// </summary>
        /// <param name="viewModel">
        ///     The specified <see cref="IViewModel" />.
        /// </param>
        /// <param name="parameter">A <see cref="T:System.Object"/> that contains data to be used for processing during navigation.</param>
        /// <param name="viewName">The specified view binding name, if any.</param>
        INavigationResult Navigate([NotNull]IViewModel viewModel, [CanBeNull]object parameter, string viewName = null);
#endif

        /// <summary>
        ///     Occurs when the page has not implemented the <see cref="IView"/> interface.
        /// </summary>
        event Action<INavigationProvider, NavigationEventArgs> NavigatingWithoutView;

        /// <summary>
        ///     Occurs when the page has been refreshed or user has gone to the page through a web browser.
        /// </summary>
        event Action<INavigationProvider, INavigationContext, IView, CancelEventArgs> NavigatingWithoutViewModel;

        /// <summary>
        ///     Occurs after page was navigated.
        /// </summary>
        event Action<INavigationProvider, INavigationContext, IViewModel> Navigated;
    }
}